package com.srmt.document.feishu.internal.table.impl;

import com.lark.oapi.service.docx.v1.model.*;
import com.srmt.document.exception.TableException;
import com.srmt.document.feishu.internal.core.BlockUtils;
import com.srmt.document.feishu.internal.table.impl.sheet.SheetReadOperations;
import com.srmt.document.feishu.internal.table.impl.sheet.SheetWriteOperations;
import com.srmt.document.feishu.internal.table.impl.sheet.SheetStructureOperations;
import com.srmt.document.feishu.internal.table.model.TableContext;
import com.srmt.document.feishu.internal.table.model.TableType;
import com.srmt.document.model.ColumnData;
import com.srmt.document.model.RowData;
import com.srmt.document.model.TableData;
import com.srmt.feishu.client.FeishuClient;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

/**
 * 电子表格操作策略实现 (blockType = 30)
 *
 * Sheet是飞书的电子表格，嵌入在文档中，通过token引用外部电子表格文档。
 * 与普通表格不同，Sheet的数据和操作需要通过Sheets API进行。
 *
 * <p><b>架构设计：</b>此类作为协调者（Coordinator），将具体操作委托给专门的操作类：
 * <ul>
 *   <li>{@link SheetReadOperations} - 处理所有读取操作</li>
 *   <li>{@link SheetWriteOperations} - 处理所有写入操作</li>
 *   <li>{@link SheetStructureOperations} - 处理结构修改操作</li>
 * </ul>
 *
 * @author srmt
 * @since 3.0.0
 */
public class SheetStrategy extends AbstractTableStrategy {

    private static final Logger logger = LoggerFactory.getLogger(SheetStrategy.class);

    // 操作类委托
    private final SheetReadOperations readOps;
    private final SheetWriteOperations writeOps;
    private final SheetStructureOperations structureOps;

    public SheetStrategy(FeishuClient client) {
        super(client, TableType.SHEET);

        // 初始化操作类
        this.readOps = new SheetReadOperations(client);
        this.writeOps = new SheetWriteOperations(client, readOps);
        this.structureOps = new SheetStructureOperations(client);

        logger.debug("电子表格策略 initialized with delegated operations");
    }

    // ========== 表格创建 ==========

    @Override
    public Block[] createTableStructure(int rows, int cols, List<List<String>> content)
            throws TableException {
        // 验证输入参数
        validateTableDimensions(rows, cols);

        logger.debug("创建 embedded sheet structure with {} rows and {} columns", rows, cols);

        // 嵌入式电子表格的创建逻辑：
        // 1. 创建Sheet Block，仅指定行列数
        // 2. 不需要预先设置token，飞书会自动生成
        // 3. 后续通过读取API获取自动生成的token

        String sheetId = generateBlockId("sheet");

        // 创建嵌入式Sheet对象
        // 注意：嵌入式电子表格不需要预先指定token
        // token会在文档创建后由飞书自动生成
        Sheet sheet = Sheet.newBuilder()
                .rowSize(rows)
                .columnSize(cols)
                // 不设置token，让飞书自动生成
                .build();

        // 创建Sheet Block
        Block sheetBlock = Block.newBuilder()
                .blockId(sheetId)
                .blockType(BlockUtils.BLOCK_TYPE_SHEET)
                .sheet(sheet)
                .children(new String[]{}) // Sheet通常没有子Block
                .build();

        logger.info("创建包含维度的嵌入式工作表块结构 {}x{}", rows, cols);

        // 嵌入式电子表格的初始内容会在创建后通过读取API获取token，
        // 然后使用Sheets API设置
        if (content != null && !content.isEmpty()) {
            logger.info("从文档获取工作表令牌后将设置初始内容");
            // 初始内容需要在获取到token后通过Sheets API设置
            // 这个操作应该在文档创建完成后进行
        }

        return new Block[]{sheetBlock};
    }

    @Override
    public String locateTableCell(TableContext context, int row, int col) throws TableException {
        if (!validateTableOperation(context)) {
            throw new TableException("工作表的表格上下文无效");
        }

        logger.debug("在工作表{}中定位单元格[{}, {}]",
                    row, col, context.getTableBlockId());

        // Sheet的单元格定位使用A1表示法
        String cellId = com.srmt.document.feishu.internal.table.util.SheetCoordinateHelper
                .convertToCellAddress(row, col);

        logger.debug("电子表格 cell location: {}", cellId);

        return cellId;
    }

    // ========== 读取操作委托 ==========

    @Override
    public String getCellContent(TableContext context, int row, int col) throws TableException {
        if (!validateTableOperation(context)) {
            throw new TableException("工作表的表格上下文无效");
        }
        return readOps.getCellContent(context, row, col);
    }

    @Override
    public int[] getTableDimensions(TableContext context) throws TableException {
        if (!validateTableOperation(context)) {
            throw new TableException("工作表的表格上下文无效");
        }
        return readOps.getTableDimensions(context);
    }

    @Override
    public TableMergeInfo[] getTableMergeInfo(TableContext context) throws TableException {
        if (!validateTableOperation(context)) {
            throw new TableException("工作表的表格上下文无效");
        }
        return readOps.getTableMergeInfo(context);
    }

    @Override
    public TableData convertToTableData(TableContext context) throws TableException {
        if (!validateTableOperation(context)) {
            throw new TableException("工作表的表格上下文无效");
        }
        return readOps.convertToTableData(context);
    }

    @Override
    public TableData buildTableFromBlocks(Block tableBlock, Map<String, Block> blockMap)
            throws TableException {
        return readOps.buildTableFromBlocks(tableBlock, blockMap);
    }

    // ========== 写入操作委托 ==========

    @Override
    public void updateCellContentByIndex(TableContext context, int row, int col, String value)
            throws TableException {
        if (!validateTableOperation(context)) {
            throw new TableException("工作表的表格上下文无效");
        }
        writeOps.updateCellContentByIndex(context, row, col, value);
    }

    @Override
    public void batchUpdateCellsByIndex(TableContext context, Map<int[], String> cellUpdates)
            throws TableException {
        if (!validateTableOperation(context)) {
            throw new TableException("工作表的表格上下文无效");
        }
        writeOps.batchUpdateCellsByIndex(context, cellUpdates);
    }

    @Override
    public void addTableRows(TableContext context, List<RowData> rows, int position)
            throws TableException {
        if (!validateTableOperation(context)) {
            throw new TableException("工作表的表格上下文无效");
        }
        writeOps.addTableRows(context, rows, position);
    }

    @Override
    public void deleteTableRows(TableContext context, int startRow, int endRow)
            throws TableException {
        if (!validateTableOperation(context)) {
            throw new TableException("工作表的表格上下文无效");
        }
        writeOps.deleteTableRows(context, startRow, endRow);
    }

    @Override
    public void addTableColumns(TableContext context, List<ColumnData> columns, int position)
            throws TableException {
        if (!validateTableOperation(context)) {
            throw new TableException("工作表的表格上下文无效");
        }
        writeOps.addTableColumns(context, columns, position);
    }

    @Override
    public void deleteTableColumns(TableContext context, int startCol, int endCol)
            throws TableException {
        if (!validateTableOperation(context)) {
            throw new TableException("工作表的表格上下文无效");
        }
        writeOps.deleteTableColumns(context, startCol, endCol);
    }

    // ========== 结构操作委托 ==========

    @Override
    public void mergeCells(TableContext context, int startRow, int startCol,
                          int endRow, int endCol) throws TableException {
        if (!validateTableOperation(context)) {
            throw new TableException("工作表的表格上下文无效");
        }
        structureOps.mergeCells(context, startRow, startCol, endRow, endCol);
    }

    @Override
    public void unmergeCells(TableContext context, int startRow, int startCol,
                            int endRow, int endCol) throws TableException {
        if (!validateTableOperation(context)) {
            throw new TableException("工作表的表格上下文无效");
        }
        structureOps.unmergeCells(context, startRow, startCol, endRow, endCol);
    }

    // SheetStrategy不需要重写isMergedCell方法
    // 因为getTableMergeInfo已经返回了正确格式的TableMergeInfo数组
    // AbstractTableStrategy的默认实现会正确处理
}
